<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>物料搜索系统</title>
    <!-- 外部资源引入 -->
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

    <!-- Tailwind 配置 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#6B7280',
                        light: '#F3F4F6',
                        dark: '#1F2937',
                        success: '#36D399',
                        warning: '#FBBD23',
                        info: '#3ABFF8',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                    boxShadow: {
                        'card': '0 4px 12px rgba(0, 0, 0, 0.05)',
                        'card-hover': '0 8px 24px rgba(0, 0, 0, 0.08)',
                    }
                },
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
            .input-search {
                @apply px-4 py-2.5 rounded-lg border focus:ring-2 focus:ring-primary/20 focus:outline-none transition-all;
            }
            .btn-primary {
                @apply bg-primary text-white px-6 py-2.5 rounded-lg hover:bg-primary/90 focus:ring-2 focus:ring-primary/50 focus:outline-none transition-all;
            }
            .btn-outline {
                @apply border border-gray-300 bg-white text-secondary px-4 py-2 rounded-lg hover:bg-gray-50 focus:ring-2 focus:ring-primary/20 focus:outline-none transition-all;
            }
            .btn-page {
                @apply btn-outline w-9 h-9 p-0 flex items-center justify-center;
            }
            .btn-page.active {
                @apply bg-primary text-white border-primary;
            }
            .table-cell {
                @apply px-4 py-4 whitespace-nowrap text-sm;
            }
            .table-hover {
                @apply hover:bg-gray-50 transition-colors;
            }
            .specs-column {
                @apply max-w-xs;
            }
            .pulse-animation {
                animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
            }
            @keyframes pulse {
                0%, 100% {
                    opacity: 1;
                }
                50% {
                    opacity: 0.7;
                }
            }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans text-dark min-h-screen flex flex-col">
<!-- 页面头部 -->
<header class="bg-white shadow-sm sticky top-0 z-10 transition-all duration-300">
    <div class="container mx-auto px-4 py-4 flex flex-col md:flex-row justify-between items-center gap-3">
        <h1 class="text-2xl md:text-[clamp(1.5rem,3vw,2rem)] font-bold text-primary flex items-center">
            <i class="fa fa-search-plus mr-2 transition-transform duration-300 hover:rotate-12"></i>
            物料搜索系统
        </h1>
        <div class="text-sm text-secondary bg-gray-50 px-3 py-1.5 rounded-full">
            支持中文、拼音、首字母检索 | 每页固定显示20条
        </div>
    </div>
</header>

<!-- 主要内容区 -->
<main class="flex-1 search-container container mx-auto px-4 py-6">
    <!-- 搜索区域卡片 -->
    <div class="bg-white rounded-xl shadow-card p-6 mb-6 transition-all duration-300 hover:shadow-card-hover border border-gray-200 hover:border-gray-300">
        <div class="flex flex-col gap-3">
            <div class="flex flex-col md:flex-row gap-3">
                <input
                        type="text"
                        id="searchInput"
                        class="input-search border-gray-300 focus:border-primary/50 flex-1 md:flex-2 lg:max-w-xl"
                        placeholder="请输入物料名称、编号、规格或拼音..."
                        autofocus
                >
                <button id="searchBtn" class="btn-primary flex items-center justify-center">
                    <i class="fa fa-search mr-2"></i>搜索
                </button>
                <button id="clearBtn" class="btn-outline flex items-center justify-center">
                    <i class="fa fa-refresh mr-2"></i>清空
                </button>
            </div>
            <!-- 输入错误提示 -->
            <div id="inputError" class="hidden text-red-500 text-sm mt-1.5">
                <i class="fa fa-exclamation-circle mr-1"></i>
                <span id="errorMsg"></span>
            </div>
            <!-- 调试信息 -->
            <div id="debugInfo" class="hidden text-xs text-gray-500 mt-1.5 p-2 bg-gray-50 rounded">
                <p>调试信息: <span id="debugText"></span></p>
            </div>
            <div class="mt-3 text-sm text-secondary bg-blue-50/70 p-2.5 rounded-lg border border-blue-100">
                <p class="flex items-center justify-between flex-wrap gap-2">
            <span class="flex items-center">
              <i class="fa fa-lightbulb-o text-warning mr-2"></i>
              示例: "测试仪"、"ceshi"、"csy"
            </span>
                    <span class="text-gray-600">
              提示：支持模糊搜索，结果按相关性排序
            </span>
                </p>
            </div>
        </div>
    </div>

    <!-- 加载状态 -->
    <div id="loading" class="hidden py-16 text-center">
        <i class="fa fa-circle-o-notch fa-spin text-3xl text-primary/80"></i>
        <p class="mt-3 text-secondary pulse-animation">正在搜索，请稍候...</p>
    </div>

    <!-- 结果统计 -->
    <div id="resultStats" class="hidden mb-4 flex flex-wrap justify-between items-center gap-3">
        <div class="text-sm text-secondary bg-gray-50 px-3 py-2 rounded-lg">
            总条数 <span id="totalCount" class="font-semibold text-primary">0</span> 条，已加载 <span id="loadedCount" class="font-semibold text-primary">0</span> 条，耗时 <span id="tookTime" class="font-semibold text-primary">0</span> 毫秒
            <span class="ml-2 px-2 py-0.5 bg-primary/10 rounded-full text-xs text-primary">每页20条</span>
        </div>
    </div>

    <!-- 结果表格 -->
    <div id="resultTable" class="hidden bg-white rounded-xl shadow-card overflow-hidden transition-all duration-300 hover:shadow-card-hover">
        <div class="overflow-x-auto">
            <table class="min-w-full divide-y divide-gray-100 w-full">
                <thead class="bg-light">
                <tr>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料名称</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料编号</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料别名</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider specs-column">规格型号</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">基本单位</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料属性</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料大类</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">物料细类</th>
                    <th class="px-4 py-3.5 text-left text-xs font-medium text-secondary uppercase tracking-wider">命中得分</th>
                </tr>
                </thead>
                <tbody id="materialList" class="bg-white divide-y divide-gray-200">
                <!-- 物料数据将通过JS动态填充 -->
                </tbody>
            </table>
        </div>
    </div>

    <!-- 空结果状态 -->
    <div id="emptyResult" class="hidden py-16 text-center">
        <i class="fa fa-search-minus text-4xl text-gray-300 mb-4"></i>
        <p class="text-gray-500">未找到匹配的物料，请尝试其他关键词</p>
    </div>

    <!-- 分页控制 -->
    <div id="pagination" class="hidden mt-6 flex flex-wrap justify-center items-center gap-2">
        <button id="firstPage" class="btn-page disabled:opacity-50 disabled:cursor-not-allowed">
            <i class="fa fa-angle-double-left"></i>
        </button>
        <button id="prevPage" class="btn-page disabled:opacity-50 disabled:cursor-not-allowed">
            <i class="fa fa-angle-left"></i>
        </button>

        <div id="pageNumbers" class="flex items-center gap-1">
            <!-- 页码按钮将动态生成 -->
        </div>

        <button id="nextPage" class="btn-page disabled:opacity-50 disabled:cursor-not-allowed">
            <i class="fa fa-angle-right"></i>
        </button>

        <div class="ml-4 text-sm text-secondary flex items-center gap-2">
            <span>第 <span id="currentPageNum" class="font-semibold text-primary">1</span> 页</span>
            <span class="text-gray-400">（基于锚点分页）</span>
        </div>
    </div>
</main>

<!-- 页脚 -->
<footer class="bg-white border-t border-gray-200 py-4 mt-8">
    <div class="container mx-auto px-4 text-center text-sm text-secondary">
        <p>物料搜索系统 &copy; 2025 | 基于search_after分页</p>
    </div>
</footer>

<script>
    // 全局状态与配置
    const pageSize = 20;
    const MAX_CACHE_SIZE = 50;
    let currentKeyword = '';
    let currentAnchor = null; // 当前页的起始锚点（[score, id]）
    let nextAnchor = null; // 下一页的起始锚点
    let hasNext = false;
    let loadedCount = 0;
    let totalCount = 0;
    let currentPage = 1;
    const searchCache = new Map(); // 使用Map实现LRU缓存
    let navigationHistory = [{ anchor: null, page: 1 }];
    let historyPosition = 0;
    let isLoading = false;

    // 验证规则
    const ALLOWED_CHARS_REG = /^[a-zA-Z0-9\u4e00-\u9fa5\s,，。:()+【】.*_-]*$/;
    const MAX_LENGTH = 100;

    // DOM元素缓存
    const el = {
        searchInput: document.getElementById('searchInput'),
        searchBtn: document.getElementById('searchBtn'),
        clearBtn: document.getElementById('clearBtn'),
        loading: document.getElementById('loading'),
        resultStats: document.getElementById('resultStats'),
        resultTable: document.getElementById('resultTable'),
        emptyResult: document.getElementById('emptyResult'),
        pagination: document.getElementById('pagination'),
        materialList: document.getElementById('materialList'),
        loadedCountEl: document.getElementById('loadedCount'),
        totalCountEl: document.getElementById('totalCount'),
        tookTimeEl: document.getElementById('tookTime'),
        prevPageBtn: document.getElementById('prevPage'),
        nextPageBtn: document.getElementById('nextPage'),
        firstPageBtn: document.getElementById('firstPage'),
        pageNumbers: document.getElementById('pageNumbers'),
        currentPageNum: document.getElementById('currentPageNum'),
        inputError: document.getElementById('inputError'),
        errorMsg: document.getElementById('errorMsg'),
        debugInfo: document.getElementById('debugInfo'),
        debugText: document.getElementById('debugText')
    };

    // 显示调试信息
    function showDebugInfo(message) {
        el.debugText.textContent = message;
        el.debugInfo.classList.remove('hidden');
        console.log('调试:', message);
    }

    // 隐藏调试信息
    function hideDebugInfo() {
        el.debugInfo.classList.add('hidden');
    }

    // 初始化事件
    function initEvents() {
        try {
            if (el.searchBtn) {
                el.searchBtn.addEventListener('click', handleSearch);
                showDebugInfo('搜索按钮事件已绑定');
            }

            if (el.searchInput) {
                el.searchInput.addEventListener('keypress', e => {
                    if (e.key === 'Enter') {
                        handleSearch();
                    }
                });
                el.searchInput.addEventListener('input', validateInput);
                el.searchInput.addEventListener('focus', validateInput);
            }

            if (el.clearBtn) {
                el.clearBtn.addEventListener('click', handleClear);
            }

            if (el.prevPageBtn) {
                el.prevPageBtn.addEventListener('click', handlePrevPage);
            }

            if (el.nextPageBtn) {
                el.nextPageBtn.addEventListener('click', handleNextPage);
            }

            if (el.firstPageBtn) {
                el.firstPageBtn.addEventListener('click', handleFirstPage);
            }

            window.addEventListener('scroll', () => {
                const header = document.querySelector('header');
                if (header) {
                    header.classList.toggle('shadow', window.scrollY > 10);
                }
            });

            showDebugInfo('所有事件初始化完成');
        } catch (error) {
            showDebugInfo(`事件初始化错误: ${error.message}`);
            console.error('事件初始化错误:', error);
        }
    }

    // 输入验证
    function validateInput() {
        const value = el.searchInput.value || '';
        let errorMsg = '';

        if (value.trim() === '') {
            errorMsg = '搜索关键字不能为空';
        } else if (value.length > MAX_LENGTH) {
            errorMsg = `搜索关键字过长，最大长度为${MAX_LENGTH}个字符`;
        } else if (!ALLOWED_CHARS_REG.test(value)) {
            errorMsg = '搜索关键字包含非法字符，支持中文、英文、数字及常见符号';
        }

        if (errorMsg) {
            el.errorMsg.textContent = errorMsg;
            el.inputError.classList.remove('hidden');
            el.searchInput.classList.add('border-red-300');
            el.searchInput.classList.remove('border-green-300');
            return false;
        } else {
            el.inputError.classList.add('hidden');
            el.searchInput.classList.remove('border-red-300');
            if (value.trim() !== '') {
                el.searchInput.classList.add('border-green-300');
            } else {
                el.searchInput.classList.remove('border-green-300');
            }
            return true;
        }
    }

    // 生成唯一缓存键 - 优化版本确保锚点一致性
    function getCacheKey() {
        // 对锚点数组进行深拷贝序列化，避免引用导致的键不一致
        const anchorStr = currentAnchor === null
            ? 'first'
            : JSON.stringify([...currentAnchor]); // 强制生成新数组，确保序列化一致
        return `${currentKeyword}-${anchorStr}`;
    }

    // LRU缓存存储策略
    function setCache(key, value) {
        // 如果缓存存在，先删除再插入（保证最新访问的在最后）
        if (searchCache.has(key)) {
            searchCache.delete(key);
        }
        // 超过最大容量时，删除最旧的缓存（Map 迭代顺序为插入顺序）
        if (searchCache.size >= MAX_CACHE_SIZE) {
            const oldestKey = searchCache.keys().next().value;
            searchCache.delete(oldestKey);
            showDebugInfo(`缓存淘汰：${oldestKey}`);
        }
        searchCache.set(key, value);
    }

    // 搜索处理
    function handleSearch() {
        try {
            showDebugInfo('开始处理搜索请求');

            if (!validateInput()) {
                showDebugInfo('输入验证失败，终止搜索');
                return;
            }

            const keyword = el.searchInput.value.trim();
            if (!keyword) {
                showDebugInfo('搜索关键词为空，终止搜索');
                return;
            }

            if (isLoading) {
                showDebugInfo('正在加载中，忽略重复请求');
                return;
            }

            const keywordChanged = currentKeyword !== keyword;
            if (keywordChanged) {
                showDebugInfo(`关键词变更: ${currentKeyword} -> ${keyword}`);
                currentKeyword = keyword;
                currentAnchor = null;
                nextAnchor = null;
                currentPage = 1;
                navigationHistory = [{ anchor: null, page: 1 }];
                historyPosition = 0;
                searchCache.clear();
            }

            const cacheKey = getCacheKey();
            if (searchCache.has(cacheKey)) {
                showDebugInfo(`从缓存加载: ${cacheKey}（页码：${currentPage}）`);
                const cachedData = searchCache.get(cacheKey);
                processData(cachedData);
            } else {
                showDebugInfo(`缓存未命中，发起请求: ${cacheKey}`);
                fetchMaterials();
            }
        } catch (error) {
            showDebugInfo(`搜索处理错误: ${error.message}`);
            console.error('搜索处理错误:', error);
        }
    }

    // 清空处理
    function handleClear() {
        el.searchInput.value = '';
        el.materialList.innerHTML = '';
        el.inputError.classList.add('hidden');
        el.searchInput.classList.remove('border-red-300', 'border-green-300');

        [el.resultStats, el.resultTable, el.pagination, el.emptyResult].forEach(e => e.classList.add('hidden'));

        currentKeyword = '';
        currentAnchor = null;
        nextAnchor = null;
        loadedCount = 0;
        totalCount = 0;
        currentPage = 1;
        navigationHistory = [{ anchor: null, page: 1 }];
        historyPosition = 0;
        searchCache.clear();
        hasNext = false;
        updatePagination();
        hideDebugInfo();
    }

    // 第一页处理
    function handleFirstPage() {
        if (currentPage === 1 || isLoading) return;

        const firstPage = navigationHistory[0];
        currentAnchor = firstPage.anchor ? [...firstPage.anchor] : null;
        currentPage = firstPage.page;
        historyPosition = 0;

        // 检查缓存
        const cacheKey = getCacheKey();
        if (searchCache.has(cacheKey)) {
            showDebugInfo(`首页缓存命中: ${cacheKey}`);
            processData(searchCache.get(cacheKey));
        } else {
            fetchMaterials();
        }
        el.resultStats.scrollIntoView({ behavior: 'smooth' });
    }

    // 上一页处理 - 优化缓存检查
    function handlePrevPage() {
        if (historyPosition <= 0 || isLoading) return;

        historyPosition--;
        const prevPage = navigationHistory[historyPosition];
        const prevAnchor = prevPage.anchor ? [...prevPage.anchor] : null;
        currentPage = prevPage.page;

        // 校验缓存是否存在，存在则直接使用
        const cacheKey = `${currentKeyword}-${prevAnchor === null ? 'first' : JSON.stringify(prevAnchor)}`;
        if (searchCache.has(cacheKey)) {
            showDebugInfo(`向前翻页命中缓存：${cacheKey}（页码：${currentPage}）`);
            currentAnchor = prevAnchor;
            processData(searchCache.get(cacheKey));
            el.resultStats.scrollIntoView({ behavior: 'smooth' });
            return;
        }

        // 缓存未命中时才请求
        currentAnchor = prevAnchor;
        fetchMaterials();
        el.resultStats.scrollIntoView({ behavior: 'smooth' });
    }

    // 下一页处理 - 优化历史记录管理
    function handleNextPage() {
        if (!hasNext || isLoading) return;

        // 保留完整历史记录，仅更新当前位置
        const currentPageRecord = {
            anchor: currentAnchor ? [...currentAnchor] : null,
            page: currentPage
        };

        // 仅当当前位置在历史末尾时才添加新记录，避免重复
        if (historyPosition === navigati·onHistory.length - 1) {
            navigationHistory.push(currentPageRecord);
        }

        historyPosition = Math.min(historyPosition + 1, navigationHistory.length - 1);
        currentAnchor = nextAnchor ? [...nextAnchor] : null;
        currentPage++;

        // 检查缓存
        const cacheKey = getCacheKey();
        if (searchCache.has(cacheKey)) {
            showDebugInfo(`向后翻页命中缓存：${cacheKey}（页码：${currentPage}）`);
            processData(searchCache.get(cacheKey));
        } else {
            fetchMaterials();
        }
        el.resultStats.scrollIntoView({ behavior: 'smooth' });
    }

    // 生成页码按钮
    function updatePageNumbers() {
        el.pageNumbers.innerHTML = '';

        const displayPages = [];
        for (let i = Math.max(1, currentPage - 2); i <= Math.min(currentPage + 2, currentPage + (hasNext ? 2 : 0)); i++) {
            displayPages.push(i);
        }

        displayPages.forEach(pageNum => {
            const pageBtn = document.createElement('button');
            pageBtn.className = `btn-page ${pageNum === currentPage ? 'active' : ''}`;
            pageBtn.textContent = pageNum;
            pageBtn.addEventListener('click', () => {
                if (pageNum === currentPage || isLoading) return;

                const diff = pageNum - currentPage;
                if (diff > 0) {
                    const steps = Math.min(diff, 5);
                    for (let i = 0; i < steps; i++) {
                        if (!hasNext) break;
                        handleNextPage();
                    }
                } else {
                    const steps = Math.min(Math.abs(diff), 5);
                    for (let i = 0; i < steps; i++) {
                        if (historyPosition <= 0) break;
                        handlePrevPage();
                    }
                }
            });
            el.pageNumbers.appendChild(pageBtn);
        });
    }

    // 检查两个锚点是否相同
    function anchorsEqual(anchor1, anchor2) {
        if (anchor1 === anchor2) return true;
        if (!anchor1 || !anchor2) return false;
        if (anchor1.length !== anchor2.length) return false;

        return anchor1.every((val, idx) => {
            if (typeof val === 'number' && typeof anchor2[idx] === 'number') {
                return Math.abs(val - anchor2[idx]) < 0.000001;
            }
            return val === anchor2[idx];
        });
    }

    // 更新分页按钮状态
    function updatePagination() {
        el.currentPageNum.textContent = currentPage;
        updatePageNumbers();

        const isFirstPage = currentPage === 1;
        el.prevPageBtn.disabled = isFirstPage || isLoading;
        el.firstPageBtn.disabled = isFirstPage || isLoading;
        el.nextPageBtn.disabled = !hasNext || isLoading;
    }

    // 渲染物料列表
    function renderMaterials(materials) {
        el.materialList.innerHTML = '';
        if (materials.length === 0) {
            el.resultTable.classList.add('hidden');
            el.emptyResult.classList.remove('hidden');
            return;
        }

        const fragment = document.createDocumentFragment();
        const getVal = v => v ?? '-';

        materials.forEach(m => {
            const row = document.createElement('tr');
            row.className = 'table-hover';
            row.innerHTML = `
          <td class="table-cell"><div class="font-medium text-primary">${getVal(m.materialName)}</div></td>
          <td class="table-cell">${getVal(m.materialCode)}</td>
          <td class="table-cell">${getVal(m.materialAlias)}</td>
          <td class="table-cell specs-column"><div class="whitespace-pre-line">${getVal(m.materialSpecs)}</div></td>
          <td class="table-cell">${getVal(m.baseUnit)}</td>
          <td class="table-cell">${getVal(m.materialAttribute)}</td>
          <td class="table-cell">${getVal(m.materialType)}</td>
          <td class="table-cell">${getVal(m.materialCategory)}</td>
          <td class="table-cell"><span class="px-2 py-1 bg-green-100 text-green-800 text-xs rounded-full">${m.score?.toFixed(2) || '0'}</span></td>
        `;
            fragment.appendChild(row);
        });

        el.materialList.appendChild(fragment);
    }

    // 处理后端返回数据
    function processData(data) {
        try {
            totalCount = data.total;
            loadedCount = data.data.length;

            // 更新统计信息
            el.totalCountEl.textContent = totalCount;
            el.loadedCountEl.textContent = loadedCount;
            el.tookTimeEl.textContent = data.took || 0;

            nextAnchor = data.nextSearchAfter ? [...data.nextSearchAfter] : null;
            hasNext = Boolean(data.hasNext);

            const cacheKey = getCacheKey();
            if (!searchCache.has(cacheKey)) {
                setCache(cacheKey, data); // 使用LRU策略存储
                showDebugInfo(`缓存新页面：${cacheKey}（页码：${currentPage}）`);
            }

            renderMaterials(data.data);

            isLoading = false;
            el.loading.classList.add('hidden');
            [el.resultStats, el.resultTable, el.pagination].forEach(e => e.classList.remove('hidden'));
            el.emptyResult.classList.add('hidden');
            updatePagination();
        } catch (error) {
            showDebugInfo(`数据处理错误: ${error.message}`);
            console.error('数据处理错误:', error);
        }
    }

    // 请求物料数据
    async function fetchMaterials() {
        try {
            if (!currentKeyword || isLoading) {
                showDebugInfo('跳过请求: 无关键词或正在加载');
                return;
            }

            isLoading = true;
            updatePagination();

            const cacheKey = getCacheKey();
            if (searchCache.has(cacheKey)) {
                showDebugInfo(`从缓存加载: ${cacheKey}`);
                processData(searchCache.get(cacheKey));
                return;
            }

            el.loading.classList.remove('hidden');
            [el.resultStats, el.resultTable, el.pagination, el.emptyResult].forEach(e => e.classList.add('hidden'));

            // 构建URL
            let urlParts = [`http://localhost:8080/api/material/search?keyword=${encodeURIComponent(currentKeyword)}`, `size=${pageSize}`];

            if (currentAnchor !== null && currentAnchor.length > 0) {
                const anchorStr = encodeURIComponent(JSON.stringify(currentAnchor));
                urlParts.push(`searchAfter=${anchorStr}`);
            }

            // 拼接完整URL
            const url = urlParts.length > 1
                ? urlParts[0] + '&' + urlParts.slice(1).join('&')
                : urlParts[0];

            showDebugInfo(`构建的请求URL: ${url}`);

            // 请求超时控制
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 10000);

            try {
                showDebugInfo(`发起请求: ${url}`);
                const response = await fetch(url, {
                    signal: controller.signal,
                    method: 'GET',
                    mode: 'cors',
                    headers: {
                        'Accept': 'application/json'
                    }
                });

                clearTimeout(timeoutId);
                showDebugInfo(`收到响应: 状态码 ${response.status}`);

                if (!response.ok) {
                    throw new Error(`HTTP错误: 状态码 ${response.status}`);
                }

                const data = await response.json();
                showDebugInfo(`请求成功，收到 ${data.data?.length || 0} 条数据`);
                processData(data);

            } catch (error) {
                clearTimeout(timeoutId);
                showDebugInfo(`请求错误: ${error.message}`);
                console.error('请求错误:', error);

                el.loading.classList.add('hidden');
                el.emptyResult.classList.remove('hidden');
                el.resultTable.classList.add('hidden');

                if (error.name === 'AbortError') {
                    el.emptyResult.innerHTML = `
              <i class="fa fa-clock-o text-4xl text-yellow-400 mb-4"></i>
              <p class="text-yellow-500">请求超时，请重试</p>
            `;
                } else if (error.message.includes('Failed to fetch')) {
                    el.emptyResult.innerHTML = `
              <i class="fa fa-wifi text-4xl text-orange-400 mb-4"></i>
              <p class="text-orange-500">无法连接到服务器，请检查网络</p>
              <p class="text-sm text-gray-500 mt-2">URL: ${url}</p>
            `;
                } else {
                    el.emptyResult.innerHTML = `
              <i class="fa fa-times-circle text-4xl text-red-400 mb-4"></i>
              <p class="text-red-500">搜索失败：${error.message}</p>
            `;
                }

                isLoading = false;
                updatePagination();
            }
        } catch (error) {
            showDebugInfo(`请求处理错误: ${error.message}`);
            console.error('请求处理错误:', error);
            isLoading = false;
            updatePagination();
        }
    }

    // 初始化时显示信息
    document.addEventListener('DOMContentLoaded', () => {
        showDebugInfo('页面加载完成，初始化事件处理...');
        initEvents();
    });
</script>
</body>
</html>
